using Microsoft.Extensions.Logging;
using TaskScheduler.Core;

namespace TaskScheduler.Tasks;

/// <summary>
/// 健康检查任务示例
/// 定期检查系统健康状态
/// </summary>
public class HealthCheckTask : ITask
{
    private readonly ILogger<HealthCheckTask> _logger;
    private readonly IHttpClientFactory _httpClientFactory;

    public HealthCheckTask(
        ILogger<HealthCheckTask> logger,
        IHttpClientFactory httpClientFactory)
    {
        _logger = logger;
        _httpClientFactory = httpClientFactory;
    }

    public string TaskName => "HealthCheckTask";
    public string Description => "系统健康检查 - 每5分钟执行一次";
    public bool IsEnabled => true;
    public string CronExpression => "*/5 * * * *"; // 每5分钟执行一次

    public async Task<TaskResult> ExecuteAsync(CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("开始健康检查...");

            var checks = new Dictionary<string, bool>();

            // 1. 检查数据库连接
            checks["数据库"] = await CheckDatabaseAsync(cancellationToken);

            // 2. 检查API服务
            checks["API服务"] = await CheckApiAsync(cancellationToken);

            // 3. 检查磁盘空间
            checks["磁盘空间"] = CheckDiskSpace();

            // 4. 检查内存使用
            checks["内存"] = CheckMemory();

            // 汇总结果
            var allHealthy = checks.All(c => c.Value);
            var failedChecks = checks.Where(c => !c.Value).Select(c => c.Key).ToList();

            if (allHealthy)
            {
                _logger.LogInformation("✅ 所有健康检查通过");
                return new TaskResult
                {
                    IsSuccess = true,
                    Message = "系统健康状态良好"
                };
            }
            else
            {
                var message = $"⚠️ 健康检查失败: {string.Join(", ", failedChecks)}";
                _logger.LogWarning(message);
                return new TaskResult
                {
                    IsSuccess = false,
                    Message = message
                };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "健康检查执行失败");
            return new TaskResult
            {
                IsSuccess = false,
                Message = ex.Message,
                Exception = ex
            };
        }
    }

    private async Task<bool> CheckDatabaseAsync(CancellationToken cancellationToken)
    {
        try
        {
            // 这里是示例代码，实际使用时需要真实的数据库检查
            await Task.Delay(50, cancellationToken);
            _logger.LogDebug("数据库连接检查: OK");
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据库连接检查失败");
            return false;
        }
    }

    private async Task<bool> CheckApiAsync(CancellationToken cancellationToken)
    {
        try
        {
            // 这里是示例代码，实际使用时需要检查真实的API端点
            await Task.Delay(50, cancellationToken);
            _logger.LogDebug("API服务检查: OK");
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "API服务检查失败");
            return false;
        }
    }

    private bool CheckDiskSpace()
    {
        try
        {
            var drives = DriveInfo.GetDrives().Where(d => d.IsReady);
            var hasEnoughSpace = drives.All(d => d.AvailableFreeSpace > 1024 * 1024 * 1024); // 至少1GB
            _logger.LogDebug("磁盘空间检查: {Status}", hasEnoughSpace ? "OK" : "WARN");
            return hasEnoughSpace;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "磁盘空间检查失败");
            return false;
        }
    }

    private bool CheckMemory()
    {
        try
        {
            var process = System.Diagnostics.Process.GetCurrentProcess();
            var memoryMB = process.WorkingSet64 / 1024 / 1024;
            var isHealthy = memoryMB < 500; // 小于500MB视为健康
            _logger.LogDebug("内存使用: {Memory}MB - {Status}", memoryMB, isHealthy ? "OK" : "WARN");
            return isHealthy;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "内存检查失败");
            return false;
        }
    }
}

